package umeng

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"time"
)

//文档地址：http://dev.umeng.com/push/android/api-doc

//Client 客户端
type Client struct {
	AndroidKey     string
	AndroidSecret  string
	IOSKey         string
	IOSSecret      string
	ProductionMode bool
}

//MessageReq 消息请求格式
type MessageReq struct {
	AppKey         string         `json:"appkey"`
	Timestamp      string         `json:"timestamp"`
	Type           string         `json:"type"`
	DeviceTokens   string         `json:"device_tokens"`
	AliasType      string         `json:"alias_type"`
	Alias          string         `json:"alias"`
	FileID         string         `json:"file_id"`
	Filter         interface{}    `json:"filter"`
	Payload        interface{}    `json:"payload"`
	Policy         *MessagePolicy `json:"policy"`
	ProductionMode bool           `json:"production_mode"` // 可选，正式/测试模式。默认为true
	Description    string         `json:"description"`     // 可选，发送消息描述，建议填写。
	MiPush         bool           `json:"mipush"`          // 可选，默认为false。当为true时，表示MIUI、EMUI、Flyme系统设备离线转为系统下发
	MiActivity     string         `json:"mi_activity"`     // 可选，mipush值为true时生效，表示走系统通道时打开指定页面acitivity的完整包路径。
}

//MessageRsp 消息返回格式
type MessageRsp struct {
	Ret  string         `json:"ret"`
	Data MessageRspData `json:"data"`
}

//MessageRspData 消息返回data格式
type MessageRspData struct {
	MsgID   string `json:"msg_id"`
	TaskID  string `json:"task_id"`
	Code    string `json:"error_code"`
	Message string `json:"error_msg"`
}

//AndroidPayLoad 安卓payload
type AndroidPayLoad struct {
	DisplayType string              `json:"display_type"`
	Body        *AndroidPayLoadBody `json:"body"`
	Extra       map[string]string   `json:"extra"`
}

//AndroidPayLoadBody 安卓payload body
type AndroidPayLoadBody struct {
	Ticker      string `json:"ticker"`
	Title       string `json:"title"`
	Text        string `json:"text"`
	Icon        string `json:"icon"`
	LargeIcon   string `json:"largeIcon"`
	Img         string `json:"img"`
	Sound       string `json:"sound"`
	BuilderID   int    `json:"builder_id"`
	PlayVibrate bool   `json:"play_vibrate"`
	PlayLights  bool   `json:"play_lights"`
	PlaySound   bool   `json:"play_sound"`
	AfterOpen   string `json:"after_open"`
	URL         string `json:"url"`
	Activity    string `json:"activity"`
	Custom      string `json:"custom"`
}

//IOSPayLoad Ios payload
type IOSPayLoad map[string]interface{}

//IOSPayLoadAPS ios payload aps
type IOSPayLoadAPS struct {
	Alert            *IOSPayLoadAPSAlert `json:"alert"`
	Badge            int                 `json:"badge"`
	Sound            string              `json:"sound"`
	ContentAvailable int                 `json:"content-available"`
	Category         string              `json:"category"` //可选，注意: ios8才支持该字段。
}

//IOSPayLoadAPSAlert IOS payload
type IOSPayLoadAPSAlert struct {
	Title    string `json:"title"`
	SubTitle string `json:"subtitle"`
	Body     string `json:"body"`
}

//MessagePolicy 发送策略
type MessagePolicy struct {
	Start           time.Time `json:"-"`
	StartTime       string    `json:"start_time"`
	Expire          time.Time `json:"-"`
	ExpireTime      string    `json:"expire_time"`
	MaxSendNum      int       `json:"max_send_num"`
	OutBizNo        string    `json:"out_biz_no"`
	ApansCollapseID string    `json:"apns_collapse_id"`
}

//TransTime 时间转换
func (p *MessagePolicy) TransTime() {
	now := time.Now()
	if p.Start.After(now) {
		p.StartTime = p.Start.Format(timeLayout)
	}
	if p.Expire.After(now) {
		p.ExpireTime = p.Expire.Format(timeLayout)
	}
}

func (client *Client) getBaseReq(deviceType string, transType string, policy *MessagePolicy) (*MessageReq, error) {
	appkey := ""
	if deviceType == deviceTypeAndroid {
		appkey = client.AndroidKey
	} else if deviceType == deviceTypeIOS {
		appkey = client.IOSKey
	} else {
		return nil, fmt.Errorf("wrong device type %s", deviceType)
	}
	timestamp := fmt.Sprintf("%d", time.Now().Unix())
	if nil != policy {
		policy.TransTime()
	}
	msgReq := &MessageReq{
		AppKey:         appkey,
		Timestamp:      timestamp,
		Type:           transType,
		ProductionMode: client.ProductionMode,
		Policy:         policy,
	}
	return msgReq, nil
}

func (client *Client) send(msgReq *MessageReq, deviceType string) (*MessageRsp, error) {
	url := fmt.Sprintf("http://%s%s", host, sendPath)
	postBody, err := json.Marshal(msgReq)
	if err != nil {
		return nil, err
	}
	secret := ""
	if deviceType == deviceTypeAndroid {
		secret = client.AndroidSecret
	}
	if deviceType == deviceTypeIOS {
		secret = client.IOSSecret
	}

	fmt.Printf("%s", string(postBody))
	fmt.Println(secret)

	sign := Md5("POST" + url + string(postBody) + secret)
	url = url + "?sign=" + sign
	bufReader := bytes.NewReader(postBody)
	resp, err := http.Post(url, "application/json", bufReader)
	defer func() {
		resp.Body.Close()
	}()
	if err != nil {
		return nil, err
	}
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	rsp := &MessageRsp{}
	err = json.Unmarshal(body, rsp)
	return rsp, nil
}
